package com.google.agerasample.slice;

import static java.util.concurrent.Executors.newSingleThreadExecutor;

import com.google.agerasample.DisplayUtil;
import com.google.agerasample.ResourceTable;
import com.google.agerasample.basicsample.ListHolder;
import com.google.agerasample.basicsample.OnClickObservable;
import com.google.agerasample.basicsamplewithoutcallback.UsernamesSupplier;
import com.google.agera.Repositories;
import com.google.agera.Repository;
import com.google.agera.Result;
import com.google.agera.Updatable;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.ToastDialog;

import java.util.List;
import java.util.concurrent.ExecutorService;

public class BasicsamwotcbkAbilitySlice extends AbilitySlice implements Updatable {
    private ListHolder listHolder;
    private Button button;

    private OnClickObservable clickObservable =
            new OnClickObservable() {
                @Override
                public void onClick(Component component) {
                    super.onClick(component);
                    showLoadingDialog();
                }
            };

    private Repository<Result<List<String>>> usernamesRepository;
    private CommonDialog commonDialog;
    private ExecutorService networkExecutor;

    private void showLoadingDialog() {
        if (commonDialog == null) {
            commonDialog = new CommonDialog(this);
            int windowHeight = DisplayUtil.getScreenHeight(this);
            int windowWidth = DisplayUtil.getScreenWidth(this);
            if (windowHeight > windowWidth) {
                commonDialog.setSize(windowWidth / 2, windowHeight / 6);
            } else {
                commonDialog.setSize(windowWidth / 3, windowHeight / 2);
            }
            commonDialog.setContentText("loading");
            commonDialog.setCornerRadius(8);
            commonDialog.show();
        }
    }

    private void hideLoadingDialog() {
        if (commonDialog != null) {
            commonDialog.hide();
            commonDialog.destroy();
            commonDialog = null;
        }
    }

    @Override
    public void onStart(Intent intent) {
        listHolder = new ListHolder(this);
        setUIContent(listHolder.createComponent());

        button = (Button) listHolder.rootLayout.findComponentById(ResourceTable.Id_btn);
        button.setClickedListener(clickObservable);

        setUpRepository();

        showLoadingDialog();
    }

    private void setUpRepository() {
        // Set up background executor
        networkExecutor = newSingleThreadExecutor();

        // Set up usernames repository
        usernamesRepository =
                Repositories.repositoryWithInitialValue(Result.<List<String>>absent())
                        .observe(clickObservable)
                        .onUpdatesPerLoop()
                        .goTo(networkExecutor)
                        .thenGetFrom(new UsernamesSupplier())
                        .compile();
    }

    @Override
    public void onActive() {
        super.onActive();
        // We make sure the main fragment observes the repository. This will also trigger the
        // repository to update itself.
        usernamesRepository.addUpdatable(this);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        // We remove the observations to avoid triggering updates when they aren't needed
        usernamesRepository.removeUpdatable(this);
    }

    /**
     * As this MainFragment is observing the {@link #usernamesRepository}, this is triggered
     * whenever the {@link #usernamesRepository} updates itself.
     */
    @Override
    public void update() {
        // Result has methods to differentiate between success and failure.
        // Process Result.isAbsent() first because Result.failed() is true if Result.isAbsent() is
        // true.
        if (usernamesRepository.get().isAbsent()) {
            showLoadingDialog();
        } else if (usernamesRepository.get().failed()) {
            // Show error message, do not update list as we still want to show the last known list
            // of usernames
            new ToastDialog(this).setText("Error refreshing usernames").show();
            hideLoadingDialog();
        } else { // Success
            // Update the list of usernames
            listHolder.listItemProvider.setData(usernamesRepository.get().get());
            listHolder.listItemProvider.notifyDataChanged();
            hideLoadingDialog();
        }
    }
}
